package com.reins.bookstore.serviceimpl;

import com.reins.bookstore.dao.BookDao;
import com.reins.bookstore.entity.Book;
import com.reins.bookstore.object.*;
import com.reins.bookstore.service.BookService;
import com.reins.bookstore.service.OrderService;
//import jdk.internal.net.http.common.Pair;
import jdk.internal.net.http.common.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Autowired
    private OrderService orderService;

    @Override
    public BookDTO findBookById(Integer id){
        Book mid_get = bookDao.findById(id);
        BookDTO res = new BookDTO(mid_get);
        return res;
    }

    @Override
    public List<BookDTO> findAllBooks(){
        List<Book> mid_get = bookDao.findAll();
        List<BookDTO> res = new LinkedList<>();
        int len = mid_get.size();

        for (int i = 0; i < len; i++) {
            BookDTO add_book_dto = new BookDTO(mid_get.get(i));
            res.add(add_book_dto);
        }
        return res;
    }

    @Override
    public List<BookDTO> findAllBooksByIds(List<Integer> id) {
        List<Book> mid_get = bookDao.findAll();
        List<BookDTO> res = new LinkedList<>();
        int len = mid_get.size();

        for (int i = 0; i < len; i++) {
            BookDTO add_book_dto = new BookDTO(mid_get.get(i));
            res.add(add_book_dto);
        }
        return res;
    }

    @Override
    public List<BookDTO> getBooks() {
        List<Book> mid_get = bookDao.findAll();
        List<BookDTO> res = new LinkedList<>();
        int len = mid_get.size();

        for (int i = 0 ;i < len ; i++){
            BookDTO add_book_dto = new BookDTO(mid_get.get(i));
            res.add(add_book_dto);
        }
        return res;
    }

    @Override
    public List<BookDTO> getBooks(String key) {
        List<Book> mid_get = bookDao.findAll();
        List<BookDTO> res = new LinkedList<>();
        List<BookDTO> filt = new LinkedList<>();

        int len = mid_get.size();

        for (Book one_book : mid_get){
//            if (one_book.getName().contains(key)){
                BookDTO add_book_dto = new BookDTO(one_book);
                res.add(add_book_dto);
//            }
        }
        for (BookDTO one_book:res){
            String name = one_book.getName();
            if (name.contains(key)){
                filt.add(one_book);
            }
        }

        return filt;
    }

    @Override
    public BookDTO saveOneBook(Book add){
        BookDTO res;
        Book book_mid = bookDao.save(add);
        res = new BookDTO(book_mid);
        return res;
    }

    @Override
    public Integer deleteOneBook(Integer id) {
        if (bookDao.findById(id) == null)
            return 0;
        else {
            bookDao.deleteById(id);
            return 1;
        }
    }

    /*
     * 得到时间范围内的书本销量排序，同时考虑分页情况
     * 如果userId = 0，那么就是查找所有用户的订单
     * 如果userId ！= 0 ，那么就是查找对应用户的订单
     */
    @Override
    public List<BookRate> getBookRate(Filter filter){
        List<BookRate> res = new ArrayList<>();
        List<OrderDTO> orderdtos = new ArrayList<>();
        // 第一个int表示bookId，用于比较
        // 第二个int表示销量统计结果
        // bookdto存储数据
        Map<Integer, Map<Integer,BookRate>> book_map;
        book_map = new HashMap<Integer, Map<Integer,BookRate>>();

        orderdtos = orderService.findAllOrders(filter);

        for (OrderDTO orderdto:orderdtos)   //遍历所有的订单
        {
            List<BasketlineDTO> lines = orderdto.getTotalorder_books();

            for (BasketlineDTO line : lines)    // 遍历订单中的书单
            {
                int bookId = line.getBookId();
                if (book_map == null) {
                    Map<Integer,BookRate> add_map_inside = new HashMap<>();
                    add_map_inside.put(line.getNum(),new BookRate(line));
                    book_map.put(bookId, add_map_inside);
                } else {
                    if (book_map.containsKey(bookId)) {
                        Map<Integer,BookRate> inside_map = book_map.get(bookId);
                        BookRate trans = inside_map.values().iterator().next();  // 转移用
                        Integer old_sum = inside_map.keySet().iterator().next();
                        Integer new_sum = line.getNum() + old_sum;
                        inside_map.put(new_sum,inside_map.remove(old_sum));
                        //                        book_map.put(bookId,Pair.create(new_sum,trans));        // 更新完细啊来那个之后放进去
                    }
                    else{
                        Map<Integer,BookRate> add_map_inside = new HashMap<>();
                        add_map_inside.put(line.getNum(),new BookRate(line));
                        book_map.put(bookId,add_map_inside);
                    }
                }
            }
        }
        // 转换为List
        for(Map<Integer,BookRate> inside_map:book_map.values()){
            BookRate add_rate = inside_map.values().iterator().next();
            add_rate.setSum(inside_map.keySet().iterator().next());
            res.add(add_rate);
        }

        // 开始排序(按照BookRate中的sum属性自动进行非升序排序)
        Collections.sort(res, new Comparator<BookRate>() {
            @Override
            public int compare(BookRate o1, BookRate o2) {
                BookRate book1 = (BookRate) o1;
                BookRate book2 = (BookRate) o2;
                return book2.getSum().compareTo(book1.getSum());
            }
        });
        // 确定排名
        int i = 1;
        for (BookRate one_rate : res){
            one_rate.setRate(i);
            i++;
        }

        return res;
    }

    @Override
    public List<BookRate> getMostHotBooks(Integer top_k){
        List<BookRate> res = new ArrayList<>();
        List<OrderDTO> orderDTOList;
        Map<Integer, BookRate> book_map = new HashMap<>();

        orderDTOList = orderService.findAllOrders();

        for(OrderDTO orderDTO:orderDTOList){
            List<BasketlineDTO> lines = orderDTO.getTotalorder_books();
            for (BasketlineDTO line:lines) {
                int bookId = line.getBookId();
                if (book_map.containsKey(bookId)) {
                    book_map.get(bookId).addSum(line.getNum());
                }else{
                    book_map.put(bookId,new BookRate(line));
                }
            }
        }
        for(BookRate inside_map : book_map.values()){
            res.add(inside_map);
        }

        Collections.sort(res, new Comparator<BookRate>() {
            @Override
            public int compare(BookRate o1, BookRate o2) {
                BookRate book1 = (BookRate) o1;
                BookRate book2 = (BookRate) o2;
                return book2.getSum().compareTo(book1.getSum());

            }
        });

        int i = 1;

        List<BookRate> top_books = new ArrayList<>();

        if(top_k == -1){
            for(BookRate book : res){
                book.setRate(i);
                ++i;
            }
            top_books = res;
        }else {
            for (; i <= top_k  && i <= res.size(); ++i) {
                top_books.add(res.get(i - 1));
                top_books.get(i - 1).setRate(i);
            }
        }
        return top_books;
    }

    @Override
    public List<BookRate> getMostExpensiveBooks(Integer front_idx, Integer end_idx, Integer top_k){
        List<BookDTO> yuan_bookDTOList = findAllBooks();
        List<BookDTO> bookDTOList = new ArrayList<>();
        List<BookRate> res = new ArrayList<>();




        Integer max_id = 0, min_id = yuan_bookDTOList.get(0).getBookId();
        for(BookDTO bookDTO : yuan_bookDTOList){
            if(bookDTO.getBookId() > max_id)
                max_id = bookDTO.getBookId();
            if(bookDTO.getBookId() < min_id)
                min_id = bookDTO.getBookId();
        }
        if(end_idx > max_id)
            end_idx = max_id;
        if(front_idx < min_id)
            front_idx = min_id;

        if(end_idx < front_idx)
            end_idx = front_idx;

        for(BookDTO bookDTO : yuan_bookDTOList){
            int bookid_tmp = bookDTO.getBookId();
            if(bookid_tmp >= front_idx && bookid_tmp <= end_idx){
                res.add(new BookRate(bookDTO));
            }
        }
        Collections.sort(res, new Comparator<BookRate>() {
            @Override
            public int compare(BookRate o1, BookRate o2) {
                BookRate book1 = (BookRate) o1;
                BookRate book2 = (BookRate) o2;
                return book2.getPrice().compareTo(book1.getPrice());

            }
        });

        int i = 1;
        List<BookRate> top_books = new ArrayList<>();
        if(top_k < 0){
            for(BookRate book : res){
                book.setRate(i);
                ++i;
            }
            top_books = res;
        }else {
            for (; i <= top_k && i <= res.size(); ++i) {
                top_books.add(res.get(i - 1));
                top_books.get(i - 1).setRate(i);
            }
        }
        return top_books;
    }


}
